Skip to content

Add support for alternate lookups to Cache<T>#9721

Merged
michaelstaib merged 6 commits into
mainfrom
mst/cache-alternate-lookup
May 17, 2026
Merged

Add support for alternate lookups to Cache<T>#9721
michaelstaib merged 6 commits into
mainfrom
mst/cache-alternate-lookup

Conversation

@michaelstaib

Copy link
Copy Markdown
Member

No description provided.

Copilot AI review requested due to automatic review settings May 17, 2026 22:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds zero-allocation span-based lookup overloads to Cache<TValue> for .NET 9+, leveraging ConcurrentDictionary.AlternateLookup<ReadOnlySpan<char>> so callers can probe and read the cache without first materializing a string. String allocation only happens on the miss path when a new entry must be inserted.

Changes:

  • Introduce a _spanLookup field initialized from _map.GetAlternateLookup<ReadOnlySpan<char>>(), guarded by #if NET9_0_OR_GREATER.
  • Add TryGet, TryAdd, and two GetOrCreate overloads accepting ReadOnlySpan<char> keys; misses fall back to string allocation and the existing string-keyed paths.
  • Add unit tests covering hit/miss/non-overwrite/factory-invocation/state-passing semantics, plus a cross-lookup test ensuring string and span lookups operate on the same underlying map.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
src/HotChocolate/Caching/src/Caching.Memory/Cache.cs Adds span-keyed TryGet/TryAdd/GetOrCreate overloads and an alternate-lookup field for .NET 9+.
src/HotChocolate/Caching/test/Caching.Memory.Tests/CacheTests.cs Adds tests for the new span-based APIs, including cross-keying with the existing string APIs.
Comments suppressed due to low confidence (1)

src/HotChocolate/Caching/src/Caching.Memory/Cache.cs:322

  • On a miss, GetOrCreate(ReadOnlySpan<char>, ..., TState) materializes the key via key.ToString() and forwards to the string-keyed GetOrCreate, which then performs another _map.TryGetValue before falling through to GetOrAdd. This makes the miss path do two dictionary lookups (one via the alternate span lookup at line 309, and another via the string-keyed map in the forwarded call). Consider calling _map.GetOrAdd(key.ToString(), ...) directly here, mirroring the string-keyed implementation, to avoid the redundant lookup on the slow path.
        // On a miss, we materialize the key and delegate to the string-keyed overload
        // so the single-race-winner invariant of GetOrAdd is preserved.
        return GetOrCreate(key.ToString(), create, state);

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/HotChocolate/Caching/src/Caching.Memory/Cache.cs
Comment thread src/HotChocolate/Caching/src/Caching.Memory/Cache.cs
Comment thread src/HotChocolate/Caching/test/Caching.Memory.Tests/CacheTests.cs
@michaelstaib michaelstaib merged commit 16a1a69 into main May 17, 2026
6 of 7 checks passed
@michaelstaib michaelstaib deleted the mst/cache-alternate-lookup branch May 17, 2026 23:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants